package com.cac.demo.controller.msSslShelves;

import com.cac.demo.service.outStoreRoom.OutStoreroomService;
import com.cac.demo.util.CreateCommonLog;
import com.cac.demo.util.GetAuthKey;
import com.cac.demo.util.R;
import com.cac.demo.entity.MsSslShelves.MsSslShelvesDTO;
import com.cac.demo.dao.gkLog.MsGkLogDao;
import com.cac.demo.dao.MsSslShelves.MsSslShelvesDao;
import com.cac.demo.service.MsSslShelves.MsSslShelvesService;
import com.cac.demo.util.HttpUtil;
import com.cac.demo.util.WcsLogRecord;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;


import com.cac.demo.util.adapter.*;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import sun.security.validator.ValidatorException;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

//import static com.sun.jmx.snmp.ThreadContext.contains;

@RestController
@Api(tags = "resource", description = "立体库货位信息接口")
@RequestMapping("/MsSslShelvesRest")
@Slf4j
public class MsSslShelvesRest extends R {

    @Autowired
    private MsSslShelvesService msSslShelvesService;
    @Autowired
    private MsGkLogDao msGkLogDao;
    @Autowired
    private Environment environment;
    @Autowired
    private OutStoreroomService outStoreroomService;
    @Autowired
    private CreateCommonLog createCommonLog;
    @Autowired
    private MsSslShelvesDao msSslShelvesDao;
    @Autowired
    private TransactionDefinition transactionDefinition;
    @Autowired
    private PlatformTransactionManager platformTransactionManager;
    @Value("${pathProperty.isTest}")
    private boolean isTest;
    @Value("${pathProperty.testCallBackUrl}")
    private String testCallBackUrl;
    @Value("${pathProperty.testSpaceCodeUrl}")
    private String testSpaceCodeUrl;
    @Autowired
    private WcsLogRecord wcsLogRecord;

    public static  List<String> moveLocations = new ArrayList<String>();
//    /**
//     * 获取巷道
//     *
//     * @param map
//     * @return
//     */
//    @PostMapping("/getRoadway")
//    public R<Map> getRoadway(@RequestBody Map map) {
//        R<Map> R = new R<>();
//        String act = (String) map.get("act");
//        if (act.equals("getRoadway")) {
//            UUID uuid = UUID.randomUUID();
//            //获取传入的开始位置
//            String startCode = map.get("startCode").toString();
//            //获取传入的容器编码
//            String palletCode = map.get("palletCode").toString();
//            if (startCode.equals("")) {
//                R.setCode("400");
//                R.setMsg("staxwrtCode不能为空");
//            } else if (palletCode.equals("")) {
//                R.setMsg("400");
//                R.setMsg("palletCode不能为空");
//            } else {
//                String dtoReturn = msSslShelvesService.getRoadway(startCode, palletCode);
//                Map result = new HashMap();
//                if (dtoReturn.equals("400")) {
//                    R.setCode("400");
//                    R.setMsg("palletCode无效或者不存在!");
//                } else {
//                    R.setCode("200");
//                    R.setMsg("操作成功！");
//                    result.put("roadway", dtoReturn);
//                    result.put("wmsTaskId", uuid);
//                    R.setData(result);
//                }
//            }
//        }
//        return R;
//    }


    /**
     * 2.2 获取可用储位
     *
     * @param map
     * @return
     */
    @PostMapping("/getSpaceCode")
    @Transactional
        public synchronized R<Map> getSpaceCode(@RequestBody Map map) {
        String id = ComUtil.getId();
        log.info("wcs调用获取可用储位" + map.toString());
        R<Map> R = new R<>();
        long beginTime = System.currentTimeMillis();
        log.info("======开始时间=======" + beginTime);
        String startCode = map.get("startCode").toString();
        //获取传入的容器编码
        String palletCode = map.get("palletCode").toString();
        //2023-05-26 yebo 添加，增加wcs日志记录
        Map extendMap = new HashMap();
        extendMap.put("callUrl", "/MsSslShelvesRest/getSpaceCode");
        extendMap.put("logType", "becall");
        extendMap.put("ID", id);

        //getspacecode 接口 taskID可能为空
        HashMap wmsTasks = msSslShelvesService.selectWmsTaskId(palletCode);
        String wmsTaskIds = "";
        if (!Objects.isNull(wmsTasks)) {
            wmsTaskIds = wmsTasks.get("wmsTaskId").toString();
        }
        //wcs日志记录
        HashMap retMap = wcsLogRecord.saveCallBackLog(map, extendMap, false, wmsTaskIds);
        if ("0".equals(retMap.get("retCode"))) {
            log.info("wms已经获取到此消息！" + map.toString());
            R.setCode("200");
            R.setMsg("wms已经获取到此消息！");
            long endTime = System.currentTimeMillis();
            log.info("========getSpaceCode====" + map.toString() + "======消耗时间=========" + (endTime - beginTime) + "ms");
            long dealTime = (endTime - beginTime);
            extendMap.put("dealTime", dealTime + "ms");
            extendMap.put("wmsResult", JSON.toJSONString(R));
            wcsLogRecord.updateLog(extendMap);
            return R;
        }

        //判断是否测试用缓存箱
        if (!Objects.isNull(msGkLogDao.selectTestBackShelves(map))) {
            /** yebo 新增判断，如果任务id是99990开通则，调用测试环境  start* */
            if (!isTest) {//当前环境为正式环境，任务id为测试环境id时，调用测试环境
                log.info("当前环境为正式环境>>>>>>>>>>>>>>>>>>>>>>>>>>>>>准备开始调用测试环境");
                String ret = HttpUtil.post(testSpaceCodeUrl, JSON.toJSONString(map));
                log.info("测试环境回调结束>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>返回值：" + ret);
                return JSON.parseObject(ret, R.getClass());
                /** yebo 新增判断，如果任务id是99990开通则，调用测试环境  end* */
            }
        }

        //任务在巷道中最大操作数量
        int sqlCount = Integer.parseInt(environment.getProperty("sqlCount.count"));
        if (startCode == null || startCode.equals("")) {
            R.setCode("400");
            R.setMsg("startCode不能为空");
        } else if (startCode == null || palletCode.equals("")) {
            R.setMsg("400");
            R.setMsg("palletCode不能为空");
        } else if (startCode.equals("1189") || startCode.equals("1185") || startCode.equals("1180") || startCode.equals("1177") || startCode.equals("1173") || startCode.equals("1169")) {
            log.info("运行开始位置为堆垛机" + startCode);
            //物料重量
            String palletWeight = map.get("palletWeight").toString();
            //货物高度
            String param = JSON.toJSONString(map.get("palletHeight"));
            Integer palletHeight = JSON.parseObject(param, Integer.class);
            HashMap wmsTask = msSslShelvesService.selectWmsTaskId(palletCode);
            if (palletWeight == null) {
                R.setCode("400");
                R.setMsg("重量不能为空");
            } else if (palletHeight == null) {
                R.setCode("400");
                R.setMsg("高度不能为空");
            } else {
//                String sqlReturn = msSslShelvesService.getSpaceCode(startCode, palletCode, palletHeight, wmsTaskId);
                String sqlReturn = msSslShelvesService.getCorrespondingShelves(palletCode);
                Map result = new HashMap();
                if (sqlReturn.equals("400")) {
                    R.setCode("400");
                    R.setMsg("货位条件不满足！");
                } else {
                    R.setCode("200");
                    R.setMsg("操作成功！");
                    result.put("startCode", startCode);
                    result.put("endCode", sqlReturn);
                    result.put("wmsTaskId", wmsTask.get("wmsTaskId"));
//                    msSslShelvesService.updateLog(result);
                    msGkLogDao.putLogParam("WCS-WMS堆垛机回调wms", map.toString(), wmsTask.get("wmsTaskId"), startCode);
                    R.setData(result);
                }
            }
        } else if (startCode.equals("1055") || startCode.equals("1067")) {
            String palletHeight = map.get("palletHeight").toString();
            log.info("运行开始位置为库内扫描位" + map.toString());
            HashMap wmsTask = msSslShelvesService.selectWmsTaskId(palletCode);
            int location = 1;
//            String sqlReturn = msSslShelvesService.getRoadWay(location, sqlCount);
            HashMap sqlReturn = msSslShelvesService.getShelves(location, sqlCount, palletHeight, palletCode, wmsTask.get("wmsTaskId"), wmsTask.get("startCode"));
            if (sqlReturn.containsKey("taskOn")) {
                log.info("任务占用巷道最大数超过" + sqlCount + "条，等待货架完成任务再分配");
                extendMap.put("attribute2","任务占用巷道最大数超过" + sqlCount + "条，等待货架完成任务再分配");
            }
            Map result = new HashMap();
            if (sqlReturn.get("retCode") != null && sqlReturn.get("retCode").equals("201")) {
                R.setCode("400");
                R.setMsg("货位条件不满足！");
            } else {
                R.setCode("200");
                R.setMsg("操作成功！");
                result.put("roadway", sqlReturn.get("ROW_NO"));
                result.put("endCode", sqlReturn.get("SHELVES_CODE"));
                result.put("wmsTaskId", wmsTask.get("wmsTaskId"));
                result.put("palletCode", palletCode);
                msGkLogDao.putLogParam("WCS-WMS库内扫描位", map.toString(), wmsTask.get("wmsTaskId"), startCode);
                R.setData(result);
            }
            long endTime = System.currentTimeMillis();
            log.info("========getSpaceCode====" + map.toString() + "======消耗时间=========" + (endTime - beginTime) + "ms");
            long dealTime = (endTime - beginTime);
            extendMap.put("dealTime", dealTime + "ms");
            extendMap.put("wmsResult", JSON.toJSONString(R));
            wcsLogRecord.updateLog(extendMap);
            return R.ok(result);
        } else if (startCode.equals("1022") || startCode.equals("1019") || startCode.equals("1084")) {

            //判断操作盘是否存在未完成任务
            int count = msGkLogDao.selectOutsideIn(palletCode);
            //判断是否为正常入库任务
            HashMap wmsTask = msSslShelvesService.selectWmsTaskId(palletCode);
            if (count == 0 && wmsTask == null) {
//                Integer uuid = UUID.randomUUID().toString().hashCode();
//                uuid = uuid < 0 ? -uuid : uuid;
//                Long wmsTaskId = Long.valueOf(uuid);
                Long wmsTaskId = createCommonLog.createWmsTaskId();
//                wmsTask.put("wmsTaskId",Long.valueOf(uuid));
                map.put("wmsTaskId", wmsTaskId);
                map.put("command", "5");
                msGkLogDao.creatLog(map, map.toString());
                //agv回箱创建操作记录
                msGkLogDao.putLogParam("WCS-WMS库外入库扫描位", map.toString(), wmsTaskId, startCode);
            } else {
                map.put("wmsTaskId", wmsTask.get("wmsTaskId"));
            }
            log.info("运行开始位置为库外扫描位" + map.toString());
            int location = 2;
            if (map.containsKey("palletHeight")) {
                String palletHeight = map.get("palletHeight").toString();
                //            String sqlReturn = msSslShelvesService.getRoadWay(location, sqlCount);
                HashMap sqlReturn = msSslShelvesService.getShelves(location, sqlCount, palletHeight, palletCode, map.get("wmsTaskId"), map.get("startCode"));
                if (sqlReturn.containsKey("taskOn")) {
                    extendMap.put("attribute2","任务占用巷道最大数超过" + sqlCount + "条，等待货架完成任务再分配");
                    log.info("任务占用巷道最大数超过" + sqlCount + "条，等待货架完成任务再分配");
                }
                Map result = new HashMap();
                if (sqlReturn.get("retCode") != null && sqlReturn.get("retCode").equals("201")) {
                    R.setCode("400");
                    R.setMsg("货位条件不满足！");
                } else if (map.get("wmsTaskId") == null) {
                    R.setCode("400");
                    R.setMsg("数据异常！");
                } else {
                    R.setCode("200");
                    R.setMsg("操作成功！");
                    result.put("roadway", sqlReturn.get("ROW_NO"));
                    result.put("endCode", sqlReturn.get("SHELVES_CODE"));
                    result.put("wmsTaskId", map.get("wmsTaskId"));
                    result.put("palletCode", palletCode);
                    msGkLogDao.putLogParam("WCS->WMS库外入库扫描位,", map.toString(), map.get("wmsTaskId"), startCode);
                    R.setData(result);
                }
            } else {
                Map result = new HashMap();
                R.setCode("200");
                R.setMsg("操作成功！");
                result.put("endCode", "k1_0_0_0");
                result.put("wmsTaskId", map.get("wmsTaskId"));
                result.put("palletCode", palletCode);
                R.setData(result);
            }
        }
        long endTime = System.currentTimeMillis();
        log.info("========getSpaceCode====" + map.toString() + "======消耗时间=========" + (endTime - beginTime) + "ms");
        long dealTime = (endTime - beginTime);
        extendMap.put("dealTime", dealTime + "ms");
        extendMap.put("wmsResult", JSON.toJSONString(R));
        wcsLogRecord.updateLog(extendMap);
        return R;
    }

//    /**
//     * 2.3 检查储位状态
//     *
//     * @param map
//     * @return
//     */
//    @PostMapping("/checkSpace")
//    public R<Map> checkSpace(@RequestBody Map map) {
//        R<Map> R = new R<>();
//            UUID uuid = UUID.randomUUID();
//            //获取传入的储位编码
//            String spaceCode = map.get("spaceCode").toString();
//            //wms任务ID
//            String wmsTaskId = map.get("wmsTaskId").toString();
//            //获取传入的容器编码
//            String palletCode = map.get("palletCode").toString();
//            if (spaceCode.equals("")) {
//                R.setCode("400");
//                R.setMsg("spaceCode不能为空");
//            } else if (palletCode.equals("")) {
//                R.setMsg("400");
//                R.setMsg("palletCode不能为空");
//            } else {
//                int sqlReturn = msSslShelvesService.checkSpace(spaceCode);
//                Map result = new HashMap();
//                if (sqlReturn == 0) {
//                    R.setCode("200");
//                    R.setMsg("操作成功");
//                } else {
//                    R.setCode("200");
//                    R.setMsg("操作失败");
//                }
//            }
//
//        return R;
//    }

    /**
     * 接收wcs反馈信息 ,WCS传入参数，调用该接口
     *
     * @return
     */
    @PostMapping("/callBack")
    public R<Map> callBack(@RequestBody Map map) throws ValidatorException {
        //wms任务ID
        String wmsTaskId = map.get("wmsTaskId").toString();
        R<Map> R = new R<>();
        String ID = ComUtil.getId();
        long beginTime = System.currentTimeMillis();
        log.info("======开始时间=======" + beginTime);
        //2023-05-26 yebo 添加，处理wcs同一个上位id多次回调，目前只处理command为1(任务启动的)，其他不管
        Map extendMap = new HashMap();
        extendMap.put("callUrl", "/MsSslShelvesRest/callBack");
        extendMap.put("logType", "becall");
        extendMap.put("ID", ID);
        HashMap retMap = wcsLogRecord.saveCallBackLog(map, extendMap, true, wmsTaskId);
        if ("0".equals(retMap.get("retCode"))) {
            log.info("wms已经获取到此消息！" + map.toString());
            R.setCode("200");
            R.setMsg("wms已经获取到此消息！");
            extendMap.put("wmsResult", JSON.toJSONString(R));
            return R;
        }

        /** yebo 新增判断，如果任务id是99990开通则，调用测试环境  start* */
        if (wmsTaskId.startsWith("99990") && !isTest) {//当前环境为正式环境，任务id为测试环境id时，调用测试环境
            log.info("当前回调为测试环境>>>>>>>>>>>>>>>>>>>>>>>>>>>>>准备开始调用测试环境");
            String ret = HttpUtil.post(testCallBackUrl, JSON.toJSONString(map));
            log.info("测试环境回调结束>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>返回值：" + ret);
            return JSON.parseObject(ret, R.getClass());
        }
        /** yebo 新增判断，如果任务id是99990开通则，调用测试环境  end* */
        String debugModel = environment.getProperty("pathProperty.deBug");

        if ("false".equals(debugModel)) {
            GetAuthKey.checkKey(map);
        }
        log.info("wcs回调wms接口，wms接收wcs返回任务运行状态" + map.toString());

        //获取传入的储位编码
        String param = JSON.toJSONString(map.get("command"));
        Integer command = JSON.parseObject(param, Integer.class);

        //获取传入的容器编码
        String palletCode = map.get("palletCode").toString();
        Map result = new HashMap();
        //调用回调方法
        Integer sqlReturn = msSslShelvesService.callBack(map);
        if (command == 0) {
            R.setCode("400");
            R.setMsg("command不能为空");
        } else if (palletCode.equals("")) {
            R.setMsg("400");
            R.setMsg("palletCode不能为空");
        } else if (wmsTaskId.equals("")) {
            R.setMsg("400");
            R.setMsg("wmsTaskId不能为空");
        } else if (sqlReturn == 1) {
            R.setCode("200");
            R.setMsg("操作成功");
        } else if (sqlReturn == 0) {
            R.setCode("400");
            R.setMsg("操作失败！");
        } else if (sqlReturn == 3) {
            result.put("isLast", "0");
            R.setCode("200");
            R.setMsg("不是最后一个工作盘");
            R.setData(result);
        } else if (sqlReturn == 2) {
            result.put("isLast", "1");
            R.setCode("200");
            R.setMsg("是最后一个工作盘");
            R.setData(result);
        } else if (sqlReturn == 4) {
            result.put("isLast", "0");
            R.setCode("200");
            R.setMsg("其他出库操作！");
            R.setData(result);
        } else if (sqlReturn == 5) {
            R.setCode("200");
            R.setMsg("设备故障！");
        }
        long endTime = System.currentTimeMillis();
        log.info("========CALlback====" + map.toString() + "======消耗时间=========" + (endTime - beginTime) + "ms");
        long dealTime = (endTime - beginTime);
        extendMap.put("dealTime", dealTime + "ms");
        extendMap.put("wmsResult", JSON.toJSONString(R));
        wcsLogRecord.updateLog(extendMap);
        return R;
    }

    @PostMapping("/doTask")
    @Transactional
    public  R<String> doTask(@RequestBody Map map) {
        log.info("调用wcs接口，下发任务" + map.toString());
        R<String> R = new R<>();
        String result = null;
        String IP = null;
        String debugModel = environment.getProperty("pathProperty.deBug");
        //主要任务id
//        Integer uuid = UUID.randomUUID().toString().hashCode();
//        uuid = uuid < 0 ? -uuid : uuid;
//        Long wmsTaskId = Long.valueOf(uuid);
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        if (request.getHeader("x-forwarded-for") == null) {
            IP = request.getRemoteAddr();
        } else {
            IP = request.getHeader("x-forwarded-for");
        }
        log.info("IP" + IP);
//        //获取任务编码
//        String param = JSON.toJSONString(map.get("command"));
//        Integer command = JSON.parseObject(param, Integer.class);
//        //获取操作位置编号
//        String operationBit = msSslShelvesService.findStartCode(IP, (String) map.get("boxType"));
//        //如果操作类型为出库2，则根据调用接口ip地址查询绑定的启动位置为结束位置
//        if (map.get("taskType") != null && map.get("taskType").equals("2")) {
//            if (!map.containsKey("agv")) {
//                map.put("endCode", "xyssj" + operationBit);
//            } else {
//                map.put("endCode", "agv");
//            }
//        }
//        //如果任务类型为，启动入库，则开始位置为根据调用接口的ip地址绑定的位置为开始位置
//        if (command == 5) {
//            map.put("startCode", operationBit);
//        }


        //获取阻挡货位信息
        ResponseMsg responseMsg = msSslShelvesService.isNeedMove(map);
        HashMap DependMap = (HashMap) responseMsg.getResponseBody();
        //2023-12-15 yebo 修改日志输出
        if(DependMap!=null){
            log.info("移库任务参数："+DependMap.toString());
        }
        //判断是否为双深位
        if ("200".equals(responseMsg.getRetCode())) {
            //2023-06-14 当前任务是否已经下发给已下发给wcs
            int count = msGkLogDao.selectUnSuccessTaskOnMaterialRece(map);
            if (count == 0) {
                //双深位，创建移库任务id
                Integer moveUuid = UUID.randomUUID().toString().hashCode();
                moveUuid = moveUuid < 0 ? -moveUuid : moveUuid;
                Long moveWmsTaskId = Long.valueOf(moveUuid);
                log.info("双深位阻挡时，移库任务id" + moveWmsTaskId);
                //获取需要出库货位的阻挡货位
                String DependLocation = (String) DependMap.get("SHELVES_CODE");
                //获取阻挡货位中的操作盘编码
                String palletCode = (String) DependMap.get("PALLET_CODE");
                String roadway = (String) DependMap.get("ROW_NO");
                map.put("roadway", roadway);
                //获取阻挡货位移库后的货位
                String endCode = msSslShelvesService.getAvailableLocation(DependMap,moveLocations.toString());
                Map moveLocation = new HashMap();
                //无可用移库位,查询剩余可用位置
                if (Objects.isNull(endCode) || "".equals(endCode)) {
                    log.info("endcode:" + endCode + "000无可用移库位,查询剩余可用位置");
                    endCode = msSslShelvesDao.getRestLocation(DependMap,moveLocations.toString());
                    moveLocation.put("endCode", endCode);
                } else {
                    moveLocation.put("endCode", endCode);
                }

                //移库位置静态变量设置 +1
                if(!moveLocations.contains(endCode)){
                    moveLocations.add(endCode);
                    log.info("当前分配位置占用+1："+moveLocations.toString());
                }
                moveLocation.put("command", "1");
                moveLocation.put("taskType", "3");
                moveLocation.put("wmsTaskId", moveWmsTaskId);
                moveLocation.put("palletCode", palletCode);
                moveLocation.put("startCode", DependLocation);
                moveLocation.put("roadway", roadway);
                moveLocation.put("preWmsTaskId",map.get("preWmsTaskId"));
                //为出库操作配置父任务id，父任务id是移库操作任务id
                map.put("parentTaskId", moveLocation.get("wmsTaskId"));
//            map.put("wmsTaskId", wmsTaskId);
                log.info("双深位阻挡时，出库任务id" + map.get("wmsTaskId"));
                log.info("遇见双深位，并且有阻挡时，下发移库操作" + moveLocation.toString());
                //下发移库任务
                msGkLogDao.creatLog(moveLocation, moveLocation.toString());
                //更新移库任务目标位的占用信息
                msSslShelvesDao.updateShelvesCode(endCode, palletCode);
                //更新出库任务父任务id
                msSslShelvesService.updateLogForMove(map);
                msGkLogDao.putLogParam("自动触发移库任务,", map.toString(), moveWmsTaskId, DependLocation);
                //下发移库指令
                msSslShelvesService.doTask(moveLocation);
                R.setCode("200");
                R.setData("成功下发移库任务，请等待移库任务完成！");
            } else {
                R.setCode("201");
                R.setData(responseMsg.getMessage());
            }
        } else if ("201".equals(responseMsg.getRetCode())) {
            log.info("不是双深位，调用wcs接口，直接下发任务" + map.toString());
            result = msSslShelvesService.doTask(map);
            if ("false".equals(debugModel)) {
                Map<String, Object> jsonMap = JSON.parseObject(result, new TypeReference<HashMap<String, Object>>() {
                });
                R.setData(jsonMap.toString());
            }
        }
        //外面位置任务未完成
        else {
            R.setCode("201");
            R.setData("外面位置任务未完成，请检查！");
        }
        return R;
    }

    /**
     * 立体库集成页面接口
     *
     * @param map
     * @return
     */
    @PostMapping("/debuggingDoTask")
    public R<String> debuggingDoTask(@RequestBody Map map) {

        long timstamp = System.currentTimeMillis();
        R<String> R = new R<>();
        log.info("立体库集成页面接口参数【" + timstamp + "】" + map.toString());
        String hcxCode = (String) map.get("palletCode");
        if (!Objects.isNull(hcxCode)) {
            if (12 != hcxCode.length()) {
                R.setCode("201");
                R.setData("输入的托盘编码格式有误，请检查！");
                return R;
            }
        } else {
            R.setCode("201");
            R.setMsg("请先输入箱号！");
            R.setData("请先输入箱号！");
            return R;
        }

        if (isTest) {
            if (Objects.isNull(msGkLogDao.selectTestBackShelves(map))) {
                R.setCode("201");
                R.setData("该托盘不能用于测试环境！");
                return R;
            }
        } else {
            if (!Objects.isNull(msGkLogDao.selectTestBackShelves(map))) {
                R.setCode("201");
                R.setData("该托盘不能用于正式环境！");
                return R;
            }
        }
        String result = null;
        String IP = null;
        String debugModel = environment.getProperty("pathProperty.deBug");
        Long wmsTaskId = createCommonLog.createWmsTaskId();
        String operationBit = "";

        //获取任务编码
        String param = JSON.toJSONString(map.get("command"));
        Integer command = JSON.parseObject(param, Integer.class);
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        if (request.getHeader("x-forwarded-for") == null) {
            IP = request.getRemoteAddr();
        } else {
            IP = request.getHeader("x-forwarded-for");
        }
        String boolPalletCode = (String) map.get("palletCode");
        if (boolPalletCode.contains("11208003")) {
            operationBit = msSslShelvesService.findStartCode(IP, "WORKBIN");
        } else {
            operationBit = msSslShelvesService.findStartCode(IP, "TOOL");
        }
        //yebo 2023-06-09 添加获取wcs任务是否完成
        wcsLogRecord.dealWmsUnFinishTask((String) map.get("palletCode"));

        //如果任务类型为，启动入库，则开始位置为根据调用接口的ip地址绑定的位置为开始位置
        if (command == 5) {
            //判断是否有货物在货架上
            HashMap isShevels = msSslShelvesService.searchWorkbinShevels(map);
            if (isShevels == null) {
                map.put("startCode", operationBit);
            } else {
                R.setCode("201");
                R.setData("该编码已在货架上，无法下发回库指令");
                return R;
            }
        }

        //获取阻挡货位信息
        ResponseMsg responseMsg = msSslShelvesService.isNeedMove(map);
        HashMap DependMap = (HashMap) responseMsg.getResponseBody();
        //事务管理
        TransactionStatus transaction = platformTransactionManager.getTransaction(transactionDefinition);
        try {
            //判断是否为双深位
            if ("200".equals(responseMsg.getRetCode())) {
                //判断是否存在未完成任务
                int count = msGkLogDao.selectUnSuccessTask(map);
                if (count == 0) {
                    //双深位，创建移库任务id
                    Integer moveUuid = UUID.randomUUID().toString().hashCode();
                    moveUuid = moveUuid < 0 ? -moveUuid : moveUuid;
                    Long moveWmsTaskId = Long.valueOf(moveUuid);
                    log.info("双深位阻挡时，移库任务id【" + timstamp + "】" + moveWmsTaskId);
                    //获取需要出库货位的阻挡货位
                    String DependLocation = (String) DependMap.get("SHELVES_CODE");
                    //获取阻挡货位中的操作盘编码
                    String palletCode = (String) DependMap.get("PALLET_CODE");

                    String roadway = (String) DependMap.get("ROW_NO");
                    map.put("roadway", roadway);
                    //获取阻挡货位移库后的货位
                    String endCode = msSslShelvesService.getAvailableLocation(DependMap,moveLocations.toString());

                    Map moveLocation = new HashMap();
                    //无可用移库位,查询剩余可用位置
                    if (Objects.isNull(endCode) || "".equals(endCode)) {
                        log.info("endcode:" + endCode + "000无可用移库位,查询剩余可用位置");
                        endCode = msSslShelvesDao.getRestLocation(DependMap,moveLocations.toString());
                        moveLocation.put("endCode", endCode);
                    } else {
                        moveLocation.put("endCode", endCode);
                    }

                    //移库位分配位置占用集合
                    if(!moveLocations.contains(endCode)){
                        moveLocations.add(endCode);
                        log.info("当前分配位置占用:"+moveLocations+"00");
                    }
                    moveLocation.put("command", "1");
                    moveLocation.put("taskType", "3");
                    moveLocation.put("wmsTaskId", moveWmsTaskId);
                    moveLocation.put("palletCode", palletCode);
                    moveLocation.put("startCode", DependLocation);

                    moveLocation.put("roadway", roadway);
                    map.put("parentTaskId", moveLocation.get("wmsTaskId"));
                    map.put("wmsTaskId", wmsTaskId);
                    log.info("双深位阻挡时，出库任务id【" + timstamp + "】" + wmsTaskId);
                    log.info("遇见双深位，并且有阻挡时，下发移库操作【" + timstamp + "】" + moveLocation.toString());

                    msGkLogDao.creatLog(map, map.toString());
                    //下发移库任务
                    msGkLogDao.creatLog(moveLocation, moveLocation.toString());
                    //更新移库任务目标位的占用信息
                    msSslShelvesDao.updateShelvesCode(endCode, palletCode);
                    msSslShelvesService.doTask(moveLocation);
                    msGkLogDao.putLogParam("自动触发移库任务,", map.toString(), moveWmsTaskId, DependLocation);
                    //更新出库任务父任务id
                    msSslShelvesService.updateLogForMove(map);
                    R.setCode("200");
                    R.setData("成功下发移库任务，等待移库任务完成！");
                } else {
                    R.setCode("201");
                    R.setData("存在重复未完成任务，请检查！");
                }
            } else if ("201".equals(responseMsg.getRetCode())) {
                map.put("wmsTaskId", wmsTaskId);
                //判断是否存在未完成任务
                int count = msGkLogDao.selectUnSuccessTask(map);
                if (count == 0) {
//                    if ("2".equals(map.get("taskType"))&& !map.containsKey("agv")) {
//                        map.put("isBack", "N");
//                    }
                    //集成页面创建单个日志
                    msGkLogDao.creatLog(map, map.toString());
                    //修改接收位出库任务缓存箱未正常回库任务：is_back->'Y'
                    Integer cnt = msGkLogDao.updateUnBackTask((String) map.get("palletCode"));
                    log.info("不是双深位，调用wcs接口，直接下发任务【" + timstamp + "】" + map.toString());
                    result = msSslShelvesService.doTask(map);
                    if ("false".equals(debugModel)) {
                        Map<String, Object> jsonMap = JSON.parseObject(result, new TypeReference<HashMap<String, Object>>() {
                        });
                        log.info("result:" + jsonMap.toString());
                        R.setData("当前缓存箱存在" + cnt + "条接收任务已改！");
                    }
                    R.setCode("200");
                    R.setMsg("成功叫箱");
                } else {
                    R.setCode("201");
                    R.setData("存在重复未完成任务，请检查！");
                }
            }
            //外面位置任务未完成
            else {
                R.setCode("201");
                R.setData(responseMsg.getMessage() == null ? "存在重复未完成任务，请检查！" : responseMsg.getMessage());
            }
            platformTransactionManager.commit(transaction);
        } catch (Exception e) {
            e.printStackTrace();
            platformTransactionManager.rollback(transaction);
            R.setCode("201");
        }
        log.info("【debuggingDoTask】反馈界面结果集【" + timstamp + "】：" + JSON.toJSONString(R));
        return R;
    }



    /*
----------------------------------------------------------------------------------------------
                                       基础数据维护
----------------------------------------------------------------------------------------------
     */

    /**
     * 新增一条数据
     *
     * @param msSslShelvesDTO
     * @return
     */
    @PostMapping("save/v1")
    @ApiOperation(value = "新增一条数据")
    public ResponseMsg<String> save(@ApiParam(value = "新增数据实体") @RequestBody MsSslShelvesDTO msSslShelvesDTO) {
        ResponseMsg<String> responseMsg = new ResponseMsg<>();
        String result = msSslShelvesService.insertMsSslShelvesDTO(msSslShelvesDTO);
        if (result.equals("200")) {
            responseMsg.setRetCode(result);
            responseMsg.setMessage("新增成功！");
        } else if (result.equals("201")) {
            responseMsg.setRetCode(result);
            responseMsg.setMessage("新增失败！");
        }
        return responseMsg;
    }

    /**
     * 批量新增数据
     *
     * @param msSslShelvesDTOS
     * @return
     */
    @PostMapping("batchSave/v1")
    @ApiOperation(value = "批量新增数据")
    public ResponseMsg<Integer> batchInsert(@ApiParam(value = "新增数据实体集合") @RequestBody List<MsSslShelvesDTO> msSslShelvesDTOS) {
        ResponseMsg<Integer> responseMsg = new ResponseMsg<>();
        responseMsg.setResponseBody(msSslShelvesService.batchInsertMsSslShelvesDTO(msSslShelvesDTOS));
        return responseMsg;
    }

    /**
     * 根据物料箱编码查询数据
     *
     * @param id
     * @return
     */
    @PostMapping("search/v1")
    @ApiOperation(value = "根据物料箱编码查询数据")
    public ResponseMsg<MsSslShelvesDTO> searchMsSslShelvesDTOById(@ApiParam(value = "物料箱编码") @RequestBody String id) {
        ResponseMsg<MsSslShelvesDTO> responseMsg = new ResponseMsg<>();
        responseMsg.setResponseBody(msSslShelvesService.searchMsSslShelvesById(id));
        return responseMsg;
    }

    /**
     * 修改数据
     *
     * @param map
     * @return
     */
    @PostMapping("update/v1")
    @ApiOperation(value = "修改数据")
    public ResponseMsg<Integer> updateMsSslShelvesDTO(@ApiParam(value = "修改数据实体") @RequestBody HashMap map) {
        ResponseMsg<Integer> responseMsg = new ResponseMsg<>();
        log.info("参数，++++++"+map);
        int rsl = msSslShelvesService.updateMsSslShelves(map);
        if ((rsl) != 0) {
            responseMsg.setRetCode("200");
            responseMsg.setMessage("更新成功！");
        } else {
            responseMsg.setRetCode("201");
            responseMsg.setMessage("更新失败！");
        }
        return responseMsg;
    }

    /**
     * 批量修改数据
     *
     * @param msSslShelvesDTOS
     * @return
     */
    @ApiOperation(value = "批量修改数据")
    @PostMapping("updateMany/v1")
    public ResponseMsg<Integer> updateMsSslShelvesDTO(@ApiParam(value = "修改数据集") @RequestBody List<HashMap> msSslShelvesDTOS) {
        ResponseMsg<Integer> responseMsg = new ResponseMsg<>();
        responseMsg.setResponseBody(msSslShelvesService.updateMsSslShelvesMany(msSslShelvesDTOS));
        return responseMsg;
    }

    /**
     * 根据条件查询数据
     *
     * @param
     * @return
     */
    @PostMapping("/searchByParams/v1")
    public PageInfo searchMsSslShelvesByParams(@RequestBody Map map) {
        HashMap queryMap = (HashMap) map.get("searchParams");
        HashMap pageMap = (HashMap) map.get("pageParameter");
        log.info("canshu :"+ queryMap.toString());
        return  msSslShelvesService.searchMsSslShelvesDTOByParams(pageMap,queryMap);
    }


    /**
     * 批量删除数据
     *
     * @param
     * @return
     */
    @PostMapping("delete/v1")
    @ApiOperation(value = "根据主键批量删除数据")
    public ResponseMsg<Integer> deleteMsSslShelvesDTO(@ApiParam(value = "主键ID") @RequestBody Map map) {
        ResponseMsg<Integer> responseMsg = new ResponseMsg<>();
        List<String> sslIds = (List<String>) map.get("sslIds");
        Map reslut = msSslShelvesService.deleteMsSslShelvesDTO(sslIds);
        responseMsg.setRetCode("200");
        responseMsg.setMessage("成功删除：" + reslut.get("sucCount") + "条数据；" + "删除失败：" + reslut.get("falCount") + "条数据,其中原因为：" + reslut.get("falReson"));
        return responseMsg;
    }

    //根据任务号查询日志
    @PostMapping("searchLog")
    public ResponseMsg<QueryRespBean<HashMap>> searchByPage(@RequestBody Map map) {
        ResponseMsg<QueryRespBean<HashMap>> responseMsg = new ResponseMsg<>();
        String startTimeParams = JSON.toJSONString(map.get("startDate"));
        Date startTime = JSON.parseObject(startTimeParams, Date.class);
        Date endTime =null;
        if(!Objects.isNull(map.get("endDate"))&&!map.get("endDate").toString().equals("")){
            String endTimeParams = JSON.toJSONString(map.get("endDate"));
            endTime = JSON.parseObject(endTimeParams, Date.class);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(endTime);
            calendar.add(Calendar.DATE, 1);
            endTime=calendar.getTime();
        }
        String page = JSON.toJSONString(map.get("pageParameter"));
        PageParameter pageParameter = JSON.parseObject(page, PageParameter.class);
        String DTO = JSON.toJSONString(map.get("searchParams"));
        HashMap searchParams = JSON.parseObject(DTO, HashMap.class);
        QueryReqBean<HashMap> queryReqBean = new QueryReqBean<>();
        queryReqBean.setPageParameter(pageParameter);
        queryReqBean.setSearchParams(searchParams);
        QueryRespBean<HashMap> result = msSslShelvesService.searchLog(queryReqBean, startTime, endTime);
        responseMsg.setResponseBody(result);
        return responseMsg;
    }

    //一键叫箱（立体库维护）
    @PostMapping("/outBatch")
    public ResponseMsg<String> outBatch(@RequestBody HashMap map) {
        ResponseMsg<String> responseMsg = new ResponseMsg<>();
        try {
            String IP = null;
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            if (request.getHeader("x-forwarded-for") == null) {
                IP = request.getRemoteAddr();
                System.out.println("IP===================================="+IP);
            } else {
                IP = request.getHeader("x-forwarded-for");
                System.out.println("IP===================================="+IP);
            }

            if (map.toString() == null) {
                responseMsg.setRetCode("201").setMessage("请先选中一条数据！");
                return responseMsg;
            }
            String hcxLocation = msSslShelvesService.findStartCode(IP, "WORKBIN");
            String toolLocation = msSslShelvesService.findStartCode(IP, "TOOL");
            List<HashMap> codes = (List<HashMap>) map.get("codes");

            for (int i = 0; i < codes.size(); i++) {
                HashMap out = codes.get(i);
                if (out.get("palletCode") == null) {
                    responseMsg.setMessage("数据异常，请检查重试！").setRetCode("201");
                    return responseMsg;
                }
                String palletCodes = (String) out.get("palletCode");
                //是缓存箱
                if (palletCodes.contains("11208003")) {
                    String Location = "xyssj" + hcxLocation;
                    int taskNum = msGkLogDao.searchCountNotBack(Location);
                    //判断缓存箱位置
                    if (!Objects.isNull(hcxLocation)) {
                        if (hcxLocation.equals("1167") || hcxLocation.equals("1165") || hcxLocation.equals("1162") || hcxLocation.equals("1160")
                                || hcxLocation.equals("1157") || hcxLocation.equals("1155")) {
                            if (taskNum >= 2) {
                                return responseMsg.setMessage("当前位置可放缓存箱数量已满，请先回库再叫箱！");
                            }
                        } else if (hcxLocation.equals("1150") || hcxLocation.equals("1140") || hcxLocation.equals("1130")
                                || hcxLocation.equals("1120") || hcxLocation.equals("1110")) {
                            if (taskNum >= 4) {
                                return responseMsg.setMessage("当前位置可放缓存箱数量已满，请先回库再叫箱！");
                            }
                        }
                    }
                } else {
                    String LocationTool = "xyssj" + toolLocation;
                    int taskNumTool = msGkLogDao.searchCountNotBack(LocationTool);
                    //托盘
                    if (!Objects.isNull(toolLocation)) {
                        if (toolLocation.equals("1146") || toolLocation.equals("1136") || toolLocation.equals("1126")
                                || toolLocation.equals("1116") || toolLocation.equals("1106")) {
                            if (taskNumTool >= 6) {
                                return responseMsg.setMessage("当前位置可放托盘数量已满，请先回库再叫箱！");
                            }
                        }
                    }
                }

                if (out.get("roadway").toString().endsWith("1")) out.put("roadway", "road1");
                if (out.get("roadway").toString().endsWith("2")) out.put("roadway", "road2");
                if (out.get("roadway").toString().endsWith("3")) out.put("roadway", "road3");
                if (out.get("roadway").toString().endsWith("4")) out.put("roadway", "road4");
                if (out.get("roadway").toString().endsWith("5")) out.put("roadway", "road5");
                if (out.get("roadway").toString().endsWith("6")) out.put("roadway", "road6");
                //判断巷道的状态
                String result = outStoreroomService.isRowOn(out);
                if (result.equals("1")) {
                    //yebo 2023-04-07判断当前叫的箱子是否已经回库
                    int ct = msSslShelvesService.searchPalletIsOnShelves((String) out.get("palletCode"));
                    if (ct == 0) {
                        return responseMsg.setMessage("当前箱子还未回库，请稍等，确认货架为占用状态在操作！").setRetCode("201");
                    }
                    //判断该箱是否存在未完成任务
                    int count = msGkLogDao.selectUnSuccessTask(out);
                    if (count == 0) {
                        if (out.get("palletCode").toString().startsWith("1")) {
                            out.put("boxType", "WORKBIN");
                            out.put("taskType", "2");
                            out.put("command", "1");
                            out.put("endCode", "xyssj" + hcxLocation);
                            out.put("isBack", "N");
                            if (hcxLocation.equals("agv")) {
                                responseMsg.setMessage("配送位无法进行叫箱操作").setRetCode("201");
                            } else {
                                R<String> r = this.debuggingDoTask(out);
                                responseMsg.setMessage(r.getData()).setRetCode(r.getCode());
                            }
                        } else {
                            out.put("boxType", "TOOL");
                            out.put("taskType", "2");
                            out.put("command", "1");
                            //托盘位置
                            out.put("endCode", "xyssj" + toolLocation);
                            if (toolLocation.equals("agv")) {
                                //agv位置
                                out.replace("endCode", "agv");
                                out.put("agv", "1");
                            }
                            if(!out.containsKey("agv")){
                                out.put("isBack","N");
                            }
                            R<String> r = this.debuggingDoTask(out);
                            responseMsg.setMessage(r.getMsg()).setRetCode(r.getCode());
                        }
                    } else {
                        responseMsg.setRetCode("201").setMessage("该箱存在未完成的任务，无法叫箱！");
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            responseMsg.setRetCode("201").setMessage("数据异常，请检查重试！");
        }
        return responseMsg;
    }


    /**
     * 为保证硬件软件双系统中的信息保持一致。
     * 信息同步接口。调用wcs系统接口，
     *
     * @return
     * @HashMap wms系统传入参数，即时间段参数。 startTime  endTime
     */
    @PostMapping("/InfoSynchroni")
    public ResponseMsg<HashMap> InfoSynchroni(@RequestBody HashMap timeMap) {
        ResponseMsg<HashMap> responseMsg = new ResponseMsg<>();
        HashMap result = new HashMap();
        //验证传入参数数据
        try {
            if (timeMap.isEmpty()) {
                responseMsg.setRetCode("201");
                responseMsg.setMessage("时间参数为空！");
            }
            result = msSslShelvesService.InfoSynchroni(timeMap);
            responseMsg.setRetCode((String) result.get("retCode"));
            responseMsg.setMessage((String) result.get("msg"));
        } catch (Exception e) {
            e.printStackTrace();
            responseMsg.setRetCode("201").setMessage("数据异常，请检查重试！");
        } finally {
            return responseMsg;
        }
    }

    //xiaojian 查看当前位置的出库任务
    @PostMapping("/taskOutQuery")
    public HashMap taskOutQuery() {
        HashMap hashMap = new HashMap();
        //获得IP
        String IP = null;
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        if (request.getHeader("x-forwarded-for") == null) {
            IP = request.getRemoteAddr();
        } else {
            IP = request.getHeader("x-forwarded-for");
        }
        //得到出库任务集合 xiaojian 5-12
        List<HashMap> result = msGkLogDao.queryGkLog(IP);
        hashMap.put("result", result);
        hashMap.put("retCode", "200");
        return hashMap;
    }

    //任务占位完成按钮 lqc
    @PostMapping("/occupyFinish")
    @Transactional
    public ResponseMsg occupyFinish(@RequestBody HashMap map) {
        ResponseMsg responseMsg = new ResponseMsg();
        List<String> IDs = (List<String>) map.get("msGkLogIds");
        int cnt = 0;
        for (String ID : IDs) {
            cnt = msGkLogDao.updateOccupyTask(ID);
        }
        if (cnt > 0) {
            responseMsg.setRetCode("200").setMessage("清理占位成功！");
        } else {
            responseMsg.setRetCode("201").setMessage("清理占位失败！");
        }
        return responseMsg;
    }
}
